package com.ihrm.system.service;

import com.ihrm.common.utils.IdWorker;
import com.ihrm.domain.system.po.Role;
import com.ihrm.domain.system.po.User;
import com.ihrm.system.dao.RoleDao;
import com.ihrm.system.dao.UserDao;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RoleDao roleDao;


    /**
     * 根据mobile查询用户
     */

    public User findByMobile(String mobile){
        return userDao.findByMobile(mobile);
    }

    /**
     * 密码是否正确
     */
    public Boolean passwordIsOk(String InputPassword, String DBPassword) {
        // 使用 BCrypt 加密密码
        boolean isPasswordValid = BCrypt.checkpw(InputPassword, DBPassword);
        return isPasswordValid;
    }

    /**
     * 1.保存用户
     */
    public void save(User user){
        user.setId(idWorker.nextId() + "");
        user.setCreateTime(new Date());
        user.setEnableState(1);
        // 使用 BCrypt 加密密码
        String password = new Md5Hash(user.getPassword(), user.getMobile(), 3).toString();// 密码、盐、加密次数
        user.setPassword(password);
        userDao.save(user);
    }

    /**
     * 2.更新用户
     */
    public void update(User user){
        // 1. 根据id查询 用户信息 先查后改
        User temp = userDao.findById(user.getId()).get();
        //2.设置部门属性
        BeanUtils.copyProperties(user, temp);
        // 3. 是否修改密码
        if (!StringUtils.isEmpty(user.getPassword())) {
            String hashedPassword = BCrypt.hashpw(user.getPassword(), BCrypt.gensalt());
            temp.setPassword(hashedPassword);
        }
        userDao.save(temp);
    }


    /**
     * 3.根据id查询用户
     */
    public User findById(String id){
        return userDao.findById(id).get();
    }

    /** 动态条件查询
     * 4.查询全部用户列表 参数：map集合的形式
     *     hasDept departmentId companyId
     */
    public Page<User> findAll(Map<String, Object> map, int page, int size){
        Specification<User> spec = new Specification<User>() {
            /**
             * 动态拼接查询条件
             * hasDept departmentId companyId
             * @return
             */
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();
                //根据请求的companyId是否为空构造查询条件
                if (!StringUtils.isEmpty(map.get("companyId"))){
                    list.add(criteriaBuilder.equal(root.get("companyId").as(String.class),map.get("companyId")));
                }
                //根据请求的部门id构造查询条件
                if (!StringUtils.isEmpty(map.get("departmentId"))){
                    list.add(criteriaBuilder.equal(root.get("departmentId").as(String.class),map.get("departmentId")));
                }
                //根据请求的hasDept判断  是否分配部门 0未分配（departmentId = null），1 已分配 （departmentId ！= null）
                if (!StringUtils.isEmpty(map.get("hasDept"))){
                    if ("0".equals(map.get("hasDept"))){
                        // 查询未分配部门的角色
                        list.add(criteriaBuilder.isNull(root.get("departmentId")));
                    } else {
                        // 已分配
                        list.add(criteriaBuilder.isNotNull(root.get("departmentId")));
                    }
                    list.add(criteriaBuilder.equal(root.get("companyId").as(String.class),map.get("companyId")));
                }
                Predicate[] predicate = new Predicate[list.size()];
                list.toArray(predicate);
//                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
                return criteriaBuilder.and(predicate);
            }
        };
        return userDao.findAll(spec, new PageRequest(page - 1, size));
    }

    /**
     * 5.根据id删除用户
     */
    public void deleteById(String id){
        userDao.deleteById(id);
    }

    /**
     * 分配角色
     */
    public void assignRoles(String userId, List<String> roleIds) {
        User user = userDao.findById(userId).get();
        Set<Role> roles = new HashSet<>();
        for (String roleId : roleIds) {
            Role role = roleDao.findById(roleId).get();
            roles.add(role);
        }
        user.setRoles(roles);
        userDao.save(user);
    }

    /**
     * 调整部门
     */
    public void changeDept(String deptId, String deptName, List<String> ids) {

    }


}
